﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Transactions;

namespace IMS_Data
{
    public class OrderReposity
    {
        public IList<order> GetOrders()
        {
            IList<order> orderList = null;
            using (IMS_Data.IMS_DBEntities ctx = new IMS_Data.IMS_DBEntities())
            {
                orderList = ctx.order.ToList();
            }
            return orderList;
        }
        public order GetLastInsertOrder()
        {
            order od = null;
            using (IMS_Data.IMS_DBEntities ctx = new IMS_Data.IMS_DBEntities())
            {
                od = ctx.order.OrderByDescending(k => k.contract_sn).FirstOrDefault();
            }

            return od;
        }
        public bool IsCompanyInOrder(int cid)
        {
            bool exists = false;

            using (IMS_Data.IMS_DBEntities ctx = new IMS_Data.IMS_DBEntities())
            {
                if (ctx.orderDetail.Where(o=>o.product.company_id == cid).Count() > 0)
                {
                    exists = true;
                }
            }

            return exists;
        }

        public bool IsProductInOrder(int pid)
        {
            bool exists = false;

            using (IMS_Data.IMS_DBEntities ctx = new IMS_Data.IMS_DBEntities())
            {
                if (ctx.orderDetail.Where(o => o.product_id == pid).Count() > 0)
                {
                    exists = true;
                }
            }

            return exists;
        }
        public void UpdateOrder(order pro,List<product> proList)
        {
            using (var transaction = new TransactionScope())
            {
                using (IMS_Data.IMS_DBEntities ctx = new IMS_Data.IMS_DBEntities())
                {

                    //ctx.order.Attach(pro);

                    //var entryState = ctx.ObjectStateManager.GetObjectStateEntry(pro);
                    //entryState.SetModifiedProperty("contract_status");
                    //ctx.SaveChanges();

                    var dbOrder = ctx.order.Include("orderDetail").First(o => o.index_id == pro.index_id);
                    var AddedDetails = pro.orderDetail.Except(dbOrder.orderDetail).ToList();
                    var RemovedDetails = dbOrder.orderDetail.Except(pro.orderDetail).ToList();
                    var ModifiedDetails = dbOrder.orderDetail.Intersect(pro.orderDetail).ToList();
                    ctx.order.ApplyCurrentValues(pro);

                    AddedDetails.ForEach(d => dbOrder.orderDetail.Add(d));
                    RemovedDetails.ForEach(d => { ctx.orderDetail.DeleteObject(d); });
                    ModifiedDetails.ForEach(d => ctx.orderDetail.ApplyCurrentValues(d));
                    ctx.SaveChanges();
                    
                }
                UpdateProductPrice(proList);
                transaction.Complete();
            }
            
        }
        public void UpdateProductPrice(List<product> pro)
        {
            ProductReposity pr = new ProductReposity();

            foreach (var p in pro)
            {
                pr.UpdateProduct(p);
                
            }
        }
        public void AddOrder(order pro, List<product> proList)
        {
            using (var transaction = new TransactionScope())
            {
                using (IMS_Data.IMS_DBEntities ctx = new IMS_Data.IMS_DBEntities())
                {
                   
                    ctx.order.AddObject(pro);
                    ctx.SaveChanges();
                }
                UpdateProductPrice(proList);
                transaction.Complete();
            }

        }
        public order GetOrderByID(string contractID)
        {
            order od = null;
            using (IMS_Data.IMS_DBEntities ctx = new IMS_Data.IMS_DBEntities())
            {
                od = (from o in ctx.order.Include("orderDetail") where o.contract_sn == contractID select o).FirstOrDefault();
                if (od != null)
                {
                    od.orderDetail.ToList().ForEach(pd => pd.productReference.Load());
                }
            }
            return od;
        }

        public List<order> GetOrderByCompanyName(string companyName)
        {
            List<order> orders = new List<order>();
            using (IMS_Data.IMS_DBEntities ctx = new IMS_Data.IMS_DBEntities())
            {
                var os = (from o in ctx.order where o.contract_supplier == companyName select o);
                orders.AddRange(os.ToArray());
            }
            return orders;
        }

        public List<order> GetOrderByContition(string companyName,
            string startDate,
            string endDate,
            string status,
            int startIndex,
            int pageSize,
            List<string> productList)
        {
            List<order> orders = new List<order>();
            using (IMS_Data.IMS_DBEntities ctx = new IMS_Data.IMS_DBEntities())
            {
                
                var result = ctx.order.AsQueryable();
                if (!string.IsNullOrEmpty(companyName))
                {
                    result = result.Where(o=>o.contract_supplier == companyName);
                }
                if (!string.IsNullOrEmpty(startDate) && !string.IsNullOrEmpty(endDate))
                {
                    DateTime start, end;
                    if (DateTime.TryParse(startDate, out start) && DateTime.TryParse(endDate, out end))
                    {
                        result = result.Where(o => o.contract_date >= start && o.contract_date <= end);
                    }
                }
                if (!string.IsNullOrEmpty(status) && status != CommonData.OrderAll)
                {
                    result = result.Where(o => o.contract_status == status);
                }
                if (productList.Count != 0)
                {
                    // 需要增加按照商品类型查询订单
                    result = result.Where(odr => odr.orderDetail.Where(ddd=>productList.Contains(ddd.product.product_name)).Count() > 0);
                }
                //result = result.OrderByDescending(o=>o.contract_date).Skip(startIndex).Take(pageSize);
                orders.AddRange(result.ToArray());
            }
            return orders;
        }

        public void DeleteOrder(order pro)
        {
            using (IMS_Data.IMS_DBEntities ctx = new IMS_Data.IMS_DBEntities())
            {
                ctx.AttachTo(ctx.DefaultContainerName + ".order", pro);
                ctx.order.DeleteObject(pro);
                ctx.SaveChanges();
            }
        }
    }
}
